#ifndef VECTOR_HH_
# define VECTOR_HH_

# include <iostream>
# include <cassert>
# include <cmath>

# include "../interface/sendable.hh"

template <unsigned int U, typename T>
class Vector: Sendable
{
public:
  // Constructeur selon U.
  Vector ();
  Vector (T val1, T val2);
  Vector (T val1, T val2, T val3);
  Vector (T val1, T val2, T val3, T val4);

  // Create a vector from 2 points.
  Vector (const Vector<U, T>& point1, const Vector<U,T>& point2);

  Vector (Vector<U, T>& vect);
  Vector (const Vector<U, T>& vect);

  // Setter.
  void operator() (unsigned int pos, T val);
  void operator() (Vector<U, T>& vect);
  void val_set (T v1, T v2);
  void val_set (T v1, T v2, T v3);
  void val_set (T v1, T v2, T v3, T v4);
  // Getter.
  T operator() (unsigned int pos) const;

  //
  Vector<U, T>& operator= (const Vector<U, T>& vect);

  Vector<U, T>& operator+= (const Vector<U, T>& vect);
  Vector<U, T>& operator-= (const Vector<U, T>& vect);

  Vector<U, T>& operator+= (const T& f);
  Vector<U, T>& operator-= (const T& f);
  Vector<U, T>& operator*= (const T& f);
  Vector<U, T>& operator/= (const T& f);

  Vector<U, T>& operator%= (const int& f);

  Vector<U, T> operator+ (const Vector<U, T>& vect) const;
  Vector<U, T> operator- (const Vector<U, T>& vect);

  Vector<U, T> operator+ (const T& f);
  Vector<U, T> operator- (const T& f);
  Vector<U, T> operator* (const T& f);
  Vector<U, T> operator/ (const T& f);

  Vector<U, T> operator% (const int& f);

  // comparaison
  bool operator== (Vector<U, T>& vect);
  bool operator== (const Vector<U, T>& vect);
  bool operator!= (Vector<U, T>& vect) const;
  bool operator!= (const Vector<U, T>& vect) const;

  // operations speciales
  float scalar (Vector<U, T>& vect);
  Vector<U, T> vectorial (Vector<U, T>& vect);
  Vector<U, T> vectorial (const Vector<U, T>& p1, const Vector<U, T>& p2, const Vector<U, T>& p3);
  float get_norme () const;

  // operateurs specifiques a l'octree et la physique
  T operator& (const T& f);
  static Vector<U, T> zero ();

  // affichage
  void print () const;

  // sending a vector3 through the network
  std::string tostring (int size) const;
  void fromstring (char* str, int size);

  virtual std::string tonet () const;

  void fromnet (const char* str, int size = 12);

protected:
  T vect_[U];
};

template <unsigned int U, typename T>
std::ofstream& operator<< (std::ofstream& o, const Vector<U, T>& v);
#include "vector.hxx"

//coordonnees en int
typedef Vector<2, int> Vector2d;
typedef Vector<3, int> Vector3d;
typedef Vector<4, int> Vector4d;

//coordonnees en float
typedef Vector<2, float> Vector2f;
typedef Vector<3, float> Vector3f;
typedef Vector<4, float> Vector4f;

#endif /// !VECTOR_HH_
